package com.bcst.factory;

import com.bcst.utils.TransactionManager;
import net.sf.cglib.proxy.Enhancer;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/*
 代理工厂类
 *@description 欢迎关注公众号 编程识堂,每日更新技术相关文章，关注我不迷路
 *@author 小堂
 *@create 2023/9/9 10:02
 */
public class ProxyFactory {

  /*  private ProxyFactory(){}

    private static  ProxyFactory proxyFactory = new ProxyFactory();

    public static ProxyFactory getInstance(){
        return proxyFactory;
    }*/

  private TransactionManager transactionManager;

    public void setTransactionManager(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    /**
     * jdk 动态代理
     * @param obj
     * @return
     */
    public Object getJdkProxy(Object obj){
       return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = null;
                try {
                  //  TransactionManager.getInstance().beginTransaction();
                    transactionManager.beginTransaction();
                    result = method.invoke(obj, args);
                    //TransactionManager.getInstance().commit();
                    transactionManager.commit();
                } catch (Exception e) {
                    e.printStackTrace();
                    //TransactionManager.getInstance().rollback();
                    transactionManager.rollback();
                    throw new Exception(e);
                }
                return result;
            }
        });
    }

    /**
     * cglib动态代理
     * @param obj
     * @return
     */
    public Object getCglibProxy(Object obj){
       return Enhancer.create(obj.getClass(), (net.sf.cglib.proxy.MethodInterceptor) (o, method, objects,methodProxy) -> {
           Object result = null;
           try {
               //  TransactionManager.getInstance().beginTransaction();
               transactionManager.beginTransaction();
               result = method.invoke(obj, objects);
               //TransactionManager.getInstance().commit();
               transactionManager.commit();
           } catch (Exception e) {
               e.printStackTrace();
               //TransactionManager.getInstance().rollback();
               transactionManager.rollback();
               throw new Exception(e);
           }
           return result;
       });
    }
}
